package com.yiren.dbaa.module.practice_set.carmodel.view;

import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.DashPathEffect;
import android.graphics.Paint;
import android.graphics.Path;
import android.graphics.drawable.BitmapDrawable;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.SurfaceHolder;
import android.view.SurfaceView;

import com.yiren.backstage.currency.bean.PointBean;
import com.yiren.backstage.currency.bean.PointExBean;
import com.yiren.dbaa.R;
import com.yiren.dbaa.util.JtsUtils;

import java.util.List;

public class CarMapView extends SurfaceView implements SurfaceHolder.Callback, Runnable {

    public final static int Accuracy_DM = 1;
    public final static int Accuracy_DM2 = 2;
    public final static int Accuracy_DM4 = 3;
    public final static int Accuracy_DM7 = 4;
    public final static int Accuracy_M = 5;
    public final static int Accuracy_M2 = 6;
    public final static int Accuracy_M4 = 7;
    public final static int Accuracy_M7 = 8;
    public final static int Accuracy_M10 = 9;

    private final static int Unit_Pixel = 100;

    private SurfaceHolder holder;
    private Paint paintText;  //文本
    private Paint paintLine;  //线
    private Paint paintFill;  //填充
    private Paint paintEffect;//虚线画笔

    private int accuracy = Accuracy_M;
    private int width, height;
    private int originX, originY;
    private int touchX, touchY;
    private int selectedIndex;    //选择的点位索引
    private boolean isShowPoint = true;  //是否显示点位
    private boolean running;   //线程是否继续执行

    private int pointState;    //后天线定位卫星数
    private float angle;
    private boolean follow = true;
    private PointBean currentPoint;
    private List<PointExBean> carModelPoints;
    private int[] margins;     //1\13.25.27.29.31与边线的距离集合
    private int framePosition = -1;    //当前边框上的点
    private PointExBean pointA;
    private PointExBean pointB;
    private PointExBean pointC;
    private PointExBean pointD;
    private JtsUtils jtsUtils;

    public List<PointExBean> getCarModelPoints() {
        return carModelPoints;
    }

    public void setCarModelPoints(List<PointExBean> carModelPoints) {
        this.carModelPoints = carModelPoints;
    }

    public CarMapView(Context context) {
        this(context, null);
    }

    public CarMapView(Context context, AttributeSet attrs) {
        this(context, attrs, 0);
    }

    public CarMapView(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        jtsUtils = new JtsUtils();
        initPaint();
        touchX = -1;
        touchY = -1;
        running = false;
        currentPoint = new PointBean();
        getHolder().addCallback(this);
    }

    private void initPaint() {
        paintText = new Paint();
        paintText.setStyle(Paint.Style.FILL);
        paintText.setAntiAlias(true);
        paintText.setStrokeWidth(1);

        paintLine = new Paint();
        paintLine.setStyle(Paint.Style.STROKE);
        paintLine.setAntiAlias(true);
        paintLine.setStrokeWidth(2);

        paintFill = new Paint();
        paintFill.setStyle(Paint.Style.FILL);
        paintFill.setAntiAlias(true);

        paintEffect = new Paint();
        paintEffect.setStyle(Paint.Style.STROKE);
        paintEffect.setColor(0xFF77BDFF);
        paintEffect.setAntiAlias(true);
        paintEffect.setPathEffect(new DashPathEffect(new float[]{2f, 2f}, 1));
    }

    @Override
    public boolean onTouchEvent(MotionEvent event) {
        if (follow) return true;
        int act = event.getAction();
        int x = (int) event.getX();
        int y = (int) event.getY();

        switch (act) {
            case MotionEvent.ACTION_DOWN:
                touchX = x;
                touchY = y;
                break;
            case MotionEvent.ACTION_MOVE:
                int dx = x - touchX;
                int dy = y - touchY;
                touchX = x;
                touchY = y;
                originX += dx;
                originY += dy;
                break;
            case MotionEvent.ACTION_UP:
                touchX = -1;
                touchY = -1;
                break;
        }
        return true;
    }


    @Override
    public void surfaceCreated(SurfaceHolder holder) {
        this.holder = holder;
        (new Thread(this)).start();
    }

    @Override
    public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
        this.width = width;
        this.height = height;
        originX = width / 2;
        originY = height / 2;
    }

    @Override
    public void surfaceDestroyed(SurfaceHolder holder) {
        running = false;
    }

    @Override
    public void run() {
        running = true;
        while (running) {
            try {
                if (holder != null) {
                    if (follow) {
                        followLocation();
                    }
                    Canvas canvas = holder.lockCanvas();
                    if (null != canvas) {
                        //旋转画布
//                        if (!isCanParamInit) { //当前为采集车辆模型状态
//                            canvas.rotate(-angle, getMeasuredWidth() / 2, getMeasuredHeight() / 2);
//                        }
                        canvas.drawColor(0xFFe8e8e8);  //设置背景颜色
//                        drawScale(canvas);             //绘制比例尺
                        drawCar(canvas);
                        drawCarPoint(canvas);
                        drawCurrentPoint(canvas);      //绘制当前点位
                        drawFrameLine(canvas);         //绘制A、B、C、D边框线
                        holder.unlockCanvasAndPost(canvas);
                    }
                }
                Thread.sleep(60);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
        running = false;
    }

    /**
     * 画地图比例值
     */
    private void drawScale(Canvas canvas) {
        Path path = new Path();
        path.moveTo(20, height - 20);
        path.lineTo(20, height - 10);
        path.lineTo(100, height - 10);
        path.lineTo(100, height - 20);
        canvas.drawPath(path, paintLine);
        paintText.setTextSize(15);
        paintText.setColor(0xFF0084FF);
        canvas.drawText(getAccuracyText(), 45, height - 18, paintText);
    }

    /**
     * 根据后天线定位卫星数显示不同的当前点颜色
     *
     * @param canvas
     */
    private void drawCurrentPoint(Canvas canvas) {
        if (pointState == 0) {
            return;
        } else if (pointState == 1) {
            paintFill.setColor(0xFFCC3333);
        } else if (pointState == 2) {
            paintFill.setColor(0xFFCCCC33);
        } else if (pointState == 3) {
            paintFill.setColor(0xFF33CC33);
        }
        canvas.drawCircle(originX + distanceToPixel(currentPoint.getX()), originY - distanceToPixel(currentPoint.getY()), 10, paintFill);
    }

    /**
     * 绘制车身线
     */
    private void drawCar(Canvas canvas) {
        if (carModelPoints != null) {
            paintLine.setColor(0xFF0084FF);
            for (int i = 1; i <= 24; i++) {
                PointExBean point1 = carModelPoints.get(i == 1 ? 24 : i - 1);
                PointExBean point2 = carModelPoints.get(i);
                drawLine(canvas, point1, point2, paintLine);
            }
        }
    }

    /**
     * 绘制车辆点位
     */
    private void drawCarPoint(Canvas canvas) {
        if (null != carModelPoints && isShowPoint) {
            for (int i = 0; i < carModelPoints.size(); i++) {
                PointExBean carModelPoint = carModelPoints.get(i);
                if (null != carModelPoint) {
                    int x = originX + distanceToPixel(carModelPoint.getX());
                    int y = originY - distanceToPixel(carModelPoint.getY());
                    if (i == 0) {
                        paintFill.setColor(0xFFE96B3A);
                        canvas.drawCircle(x, y, 18, paintFill);
                    } else if (selectedIndex == i) {
                        paintFill.setColor(0xFF10C458);
                        canvas.drawCircle(x, y, 10, paintFill);
                    } else {
                        paintFill.setColor(0xFF0084FF);
                        canvas.drawCircle(x, y, 10, paintFill);
                    }
                    paintText.setColor(0xFFFFFFFF);
                    if (i == 0) {
                        paintText.setTextSize(20);
                        canvas.drawText(i + "", x - 6, y + 6, paintText);
                    } else if (i < 10) {
                        paintText.setTextSize(10);
                        canvas.drawText(i + "", x - 4, y + 4, paintText);
                    } else {
                        paintText.setTextSize(10);
                        canvas.drawText(i + "", x - 7, y + 4, paintText);
                    }
                }
            }
        }
    }

    /**
     * 绘制边框线
     */
    private void drawFrameLine(Canvas canvas) {
        drawLine(canvas, pointA, pointB, paintLine);
        drawLine(canvas, pointB, pointC, paintLine);
        drawLine(canvas, pointC, pointD, paintLine);
        drawLine(canvas, pointA, pointD, paintLine);
        drawPoint(canvas, pointA, "A", framePosition == 0);
        drawPoint(canvas, pointB, "B", framePosition == 1);
        drawPoint(canvas, pointC, "C", framePosition == 2);
        drawPoint(canvas, pointD, "D", framePosition == 3);
        if (isShowPoint) {
            drawMarginLine(canvas);
        }
    }

    /**
     * 根据坐标点绘制线
     */
    public void drawLine(Canvas canvas, PointBean point1, PointBean point2, Paint paint) {
        if (null != point1 && null != point2) {
            canvas.drawLine(originX + distanceToPixel(point1.getX()), originY - distanceToPixel(point1.getY()),
                    originX + distanceToPixel(point2.getX()), originY - distanceToPixel(point2.getY()), paint);
        }
    }

    /**
     * 根据坐标点绘制文本
     */
    public void drawPoint(Canvas canvas, PointExBean point, String text, boolean isCurrentPoint) {
        if (null != point) {
            int x = originX + distanceToPixel(point.getX());
            int y = originY - distanceToPixel(point.getY());
            paintFill.setColor(isCurrentPoint ? 0xFF10C458 : 0xFF0084FF);
            canvas.drawCircle(x, y, 16, paintFill);
            paintText.setTextSize(16);
            paintText.setColor(0xFFFFFFFF);
            canvas.drawText(text, x - 5, y + 5, paintText);
        }
    }

    /**
     * 绘制边距线和点
     *
     * @param canvas
     */
    private void drawMarginLine(Canvas canvas) {
        Bitmap bitmap = ((BitmapDrawable) getResources().getDrawable(R.mipmap.car_bj_point)).getBitmap();
        int bitmapW = bitmap.getWidth();
        int bitmapH = bitmap.getHeight();
        if (null != bitmap && null != margins && null != carModelPoints) {
            paintText.setTextSize(12);
            paintText.setColor(0xFF1E1E1E);
            if (margins[0] != 0) drawMargin1(canvas, bitmap, bitmapW, bitmapH);
            if (margins[1] != 0) drawMargin13(canvas, bitmap, bitmapW, bitmapH);
            if (margins[2] != 0) drawMargin25(canvas, bitmap, bitmapW, bitmapH);
            if (margins[3] != 0) drawMargin27(canvas, bitmap, bitmapW, bitmapH);
            if (margins[4] != 0) drawMargin29(canvas, bitmap, bitmapW, bitmapH);
            if (margins[5] != 0) drawMargin31(canvas, bitmap, bitmapW, bitmapH);
        }
    }

    /**
     * 绘制1点的边距
     */
    private void drawMargin1(Canvas canvas, Bitmap bitmap, int bitmapW, int bitmapH) {
        if (null != carModelPoints.get(1) && null != pointA && null != pointB) {
            PointExBean point1 = carModelPoints.get(1);
            if (null != point1) {
                PointBean foot = jtsUtils.getPointFoot(pointA, pointB, point1);
                if (null != foot) {
                    canvas.drawBitmap(bitmap, originX + distanceToPixel(foot.getX()) - bitmapW / 2, originY - distanceToPixel(foot.getY()) - bitmapH / 2, null);
                    drawLine(canvas, point1, foot, paintEffect);
                    canvas.drawText("" + margins[0], originX + distanceToPixel(foot.getX()) + 6, originY - distanceToPixel(foot.getY()) - 10, paintText);
                }
            }
        }
    }

    /**
     * 绘制13点的边距
     */
    private void drawMargin13(Canvas canvas, Bitmap bitmap, int bitmapW, int bitmapH) {
        if (null != carModelPoints.get(13) && null != pointC && null != pointD) {
            PointExBean point13 = carModelPoints.get(13);
            if (null != point13) {
                PointBean foot = jtsUtils.getPointFoot(pointC, pointD, point13);
                if (null != foot) {
                    canvas.drawBitmap(bitmap, originX + distanceToPixel(foot.getX()) - bitmapW / 2, originY - distanceToPixel(foot.getY()) - bitmapH / 2, null);
                    drawLine(canvas, point13, foot, paintEffect);
                    canvas.drawText("" + margins[1], originX + distanceToPixel(foot.getX()) + 6, originY - distanceToPixel(foot.getY()) - 10, paintText);
                }
            }
        }
    }

    /**
     * 绘制25点的边距
     *
     * @param bitmapW 图片的宽
     * @param bitmapH 图片的高
     */
    private void drawMargin25(Canvas canvas, Bitmap bitmap, int bitmapW, int bitmapH) {
        if (null != carModelPoints.get(25) && null != pointA && null != pointD) {
            PointExBean point25 = carModelPoints.get(25);
            if (null != point25) {
                PointBean foot = jtsUtils.getPointFoot(pointA, pointD, point25);
                if (null != foot) {
                    canvas.drawBitmap(bitmap, originX + distanceToPixel(foot.getX()) - bitmapW / 2, originY - distanceToPixel(foot.getY()) - bitmapH / 2, null);
                    drawLine(canvas, point25, foot, paintEffect);
                    canvas.drawText("" + margins[2], originX + distanceToPixel(foot.getX()) + 10, originY - distanceToPixel(foot.getY()) - 6, paintText);
                }
            }
        }
    }

    /**
     * 绘制27点的边距
     */
    private void drawMargin27(Canvas canvas, Bitmap bitmap, int bitmapW, int bitmapH) {
        if (null != carModelPoints.get(27) && null != pointB && null != pointC) {
            PointExBean point27 = carModelPoints.get(27);
            if (null != point27) {
                PointBean foot = jtsUtils.getPointFoot(pointB, pointC, point27);
                if (null != foot) {
                    canvas.drawBitmap(bitmap, originX + distanceToPixel(foot.getX()) - bitmapW / 2, originY - distanceToPixel(foot.getY()) - bitmapH / 2, null);
                    drawLine(canvas, point27, foot, paintEffect);
                    canvas.drawText("" + margins[3], originX + distanceToPixel(foot.getX()) + 10, originY - distanceToPixel(foot.getY()) - 6, paintText);
                }
            }
        }
    }

    /**
     * 绘制29点的边距
     */
    private void drawMargin29(Canvas canvas, Bitmap bitmap, int bitmapW, int bitmapH) {
        if (null != carModelPoints.get(29) && null != pointA && null != pointD) {
            PointExBean point29 = carModelPoints.get(29);
            if (null != point29) {
                PointBean foot = jtsUtils.getPointFoot(pointA, pointD, point29);
                if (null != foot) {
                    canvas.drawBitmap(bitmap, originX + distanceToPixel(foot.getX()) - bitmapW / 2, originY - distanceToPixel(foot.getY()) - bitmapH / 2, null);
                    drawLine(canvas, point29, foot, paintEffect);
                    canvas.drawText("" + margins[4], originX + distanceToPixel(foot.getX()) + 10, originY - distanceToPixel(foot.getY()) - 6, paintText);
                }
            }
        }
    }

    /**
     * 绘制31点的边距
     */
    private void drawMargin31(Canvas canvas, Bitmap bitmap, int bitmapW, int bitmapH) {
        if (null != carModelPoints.get(31) && null != pointB && null != pointC) {
            PointExBean point31 = carModelPoints.get(31);
            if (null != point31) {
                PointBean foot = jtsUtils.getPointFoot(pointB, pointC, point31);
                if (null != foot) {
                    canvas.drawBitmap(bitmap, originX + distanceToPixel(foot.getX()) - bitmapW / 2, originY - distanceToPixel(foot.getY()) - bitmapH / 2, null);
                    drawLine(canvas, point31, foot, paintEffect);
                    canvas.drawText("" + margins[5], originX + distanceToPixel(foot.getX()) + 10, originY - distanceToPixel(foot.getY()) - 6, paintText);
                }
            }
        }
    }

    public void setAccuracy(boolean up) {
        float x = pixelToDistance(width / 2 - originX);
        float y = pixelToDistance(originY - height / 2);
        accuracy = up ? accuracy + 1 : accuracy - 1;
        if (accuracy < Accuracy_DM) accuracy = Accuracy_DM;
        if (accuracy > Accuracy_M10) accuracy = Accuracy_M10;
        originX = width / 2 - distanceToPixel(x);
        originY = height / 2 + distanceToPixel(y);
    }

    public void setSelectedIndex(int selectedIndex) {
        this.selectedIndex = selectedIndex;
        if (null != carModelPoints && 0 <= selectedIndex && selectedIndex < carModelPoints.size()) {
            PointExBean point = carModelPoints.get(selectedIndex);
            if (null != point) {
                float x = distanceToPixel(point.getX());
                float y = distanceToPixel(point.getY());
                originX = (int) (width / 2 - x);
                originY = (int) (height / 2 + y);
            }
        }
    }

    public void setCurrentPoint(float x, float y, int state) {
        if (null != carModelPoints && carModelPoints.size() > 0 && null != carModelPoints.get(0)) {
            if (null != carModelPoints.get(0)) {
                if (carModelPoints.get(0).getX() == 0) {
                    currentPoint.setPoint(0, 0);
                } else {
                    currentPoint.setPoint(x, y);
                }
            } else {
                currentPoint.setPoint(x, y);
            }
        }
        pointState = state;
    }

    public void setAngle(float angle) {
        this.angle = angle;
    }

    public void setFollow(boolean follow) {
        this.follow = follow;
    }

    /**
     * 设置当前采集的边框点
     */
    public void setFramePoint(int framePosition, PointExBean point) {
        this.framePosition = framePosition;
        if (framePosition == 0) pointA = point;
        else if (framePosition == 1) pointB = point;
        else if (framePosition == 2) pointC = point;
        else if (framePosition == 3) pointD = point;
    }

    public void setShowMargin(int[] showMargin) {
        margins = new int[showMargin.length];
        for (int i = 0; i < showMargin.length; i++) {
            margins[i] = showMargin[i];
        }
    }

    public boolean isShowPoint() {
        return isShowPoint;
    }

    public void setShowPoint(boolean showPoint) {
        this.isShowPoint = showPoint;
    }

    private int distanceToPixel(float distance) {
        float scale = getAccuracyScale();
        return (int) (distance * scale * Unit_Pixel);
    }

    private float pixelToDistance(int pixel) {
        float scale = getAccuracyScale();
        return ((float) pixel) / (scale * Unit_Pixel);
    }

    private void followLocation() {
        if (currentPoint != null) {
            float x = distanceToPixel(currentPoint.getX());
            float y = distanceToPixel(currentPoint.getY());
            originX = (int) (width / 2 - x);
            originY = (int) (height / 2 + y);
        }
    }

    private float getAccuracyScale() {
        switch (accuracy) {
            case Accuracy_DM:
                return 10.0f;
            case Accuracy_DM2:
                return 5.0f;
            case Accuracy_DM4:
                return 2.5f;
            case Accuracy_DM7:
                return 1.428f;
            case Accuracy_M:
                return 1.0f;
            case Accuracy_M2:
                return 0.5f;
            case Accuracy_M4:
                return 0.25f;
            case Accuracy_M7:
                return 0.1428f;
            case Accuracy_M10:
                return 0.1f;
            default:
                return 1.0f;
        }
    }

    public String getAccuracyText() {
        switch (accuracy) {
            case Accuracy_DM:
                return " 分米 ";
            case Accuracy_DM2:
                return "2分米";
            case Accuracy_DM4:
                return "4分米";
            case Accuracy_DM7:
                return "7分米";
            case Accuracy_M:
                return "  米  ";
            case Accuracy_M2:
                return " 2米 ";
            case Accuracy_M4:
                return " 4米 ";
            case Accuracy_M7:
                return " 7米 ";
            case Accuracy_M10:
                return "10米";
            default:
                return " 未知 ";
        }
    }

}